Repository navigation
Conversation
The nine codecvt<char, char, _Mbstatet> exports threw. The do_ members now run libc's C-locale conversion table, which libc returns from LibcCodecvtMethods_nid_no_patch without adding any libc export, and in, out, unshift and length call the facet's vtable slot as [locale.codecvt.members] requires. libc's do_unshift now returns noconv, which [locale.codecvt.virtuals] fixes for this specialization. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Progress report (b11c7bf → 24e3728)📈 System libraries: 26.73% (+0.02%, +9 implemented, -9 removed functions) ✅ 9 implemented
🗑️ 9 removed
Changed libraries (implemented exports)
|
|
Thank you for your contribution! Authors with no pull requests merged into |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
This implements nine
std::codecvt<char, char, _Mbstatet>members in libSceLibcInternal. Onmaineach one threw throughNotImplemented_nid_no_patch(sceLibcInternalPending3_027..035inErr.cpp):_ZNKSt7codecvtIcc9_MbstatetE16do_always_noconvEv7tIwDZyyKHoCodecvtAlwaysNoconv:true_ZNKSt7codecvtIcc9_MbstatetE5do_inERS0_PKcS4_RS4_PcS6_RS6_P+q1OLiErP0CodecvtNoConversion:noconv,from_next = from,to_next = to_ZNKSt7codecvtIcc9_MbstatetE6do_outERS0_PKcS4_RS4_PcS6_RS6_Uc+-Sx0UZ3UCodecvtNoConversion_ZNKSt7codecvtIcc9_MbstatetE10do_unshiftERS0_PcS3_RS3_iCWgjeqMHvgCodecvtUnshift:noconv,to_next = to_ZNKSt7codecvtIcc9_MbstatetE9do_lengthERS0_PKcS4_mXk7IZcfHDD8CodecvtLength:min(from_end - from, max)_ZNKSt7codecvtIcc9_MbstatetE2inERS0_PKcS4_RS4_PcS6_RS6_TNexGlwiVEQdo_inthrough the facet's vtable (CodecvtVtable::in, offset 0x38)_ZNKSt7codecvtIcc9_MbstatetE3outERS0_PKcS4_RS4_PcS6_RS6_14xKj+SV72odo_out(CodecvtVtable::out, offset 0x40)_ZNKSt7codecvtIcc9_MbstatetE7unshiftERS0_PcS3_RS3_N7z+Dnk1cS0do_unshift(CodecvtVtable::unshift, offset 0x48)_ZNKSt7codecvtIcc9_MbstatetE6lengthERS0_PKcS4_mikBt0lqkxPcdo_length(CodecvtVtable::length, offset 0x50)The behaviour comes from [locale.codecvt.virtuals] (checked against the current draft, eel.is/c++draft/locale.codecvt.virtuals) and matches microsoft/STL
e1ed302683stl/inc/xlocale:do_inanddo_out: Table 93 givesnoconvwhen "internT and externT are the same type, and input sequence is identical to converted sequence";from_next = from,to_next = to.do_unshift: Table 94 givesnoconvwhen "no termination is needed for this state_type"; xlocale L738-L742 sets_Mid2 = _First2and returnsnoconv.do_always_noconv: "codecvt<char, char, mbstate_t> returns true."do_length: for this specialization, "returns the lesser of max and (from_end - from)".[locale.codecvt.members] makes each public member return its
do_member. For exampleinis "Returns: do_in(state, from, from_end, from_next, to, to_end, to_next)".libc already holds these conversions.
_ZNSt7codecvtIcc9_MbstatetE7_Getcatbuilds its C-locale facet ong_codecvtVtableincore/libs/prx/libc/src/LocaleSupport.cpp:const GuestLocale::CodecvtVtable g_codecvtVtable{{DestroyCollate, DeleteCollate, RetainFacet, ReleaseFacet}, CodecvtAlwaysNoconv, CodecvtConstantOne, CodecvtConstantOne, CodecvtNoConversion, CodecvtNoConversion, CodecvtUnshift, CodecvtLength};The slot layout is pinned in
GuestLocale.hppbystatic_assert(offsetof(CodecvtVtable, alwaysNoconv) == 0x20),in == 0x38andlength == 0x50. Following #14373, which reaches libc'snumpunct<char>helpers through a libc header instead of copying them, libc now returns that table fromLibcCodecvtMethods_nid_no_patch(), declared inprx/libc/include/GuestLocale.hpp. The_nid_no_patchsuffix keeps it out of the NID tables, so libc gets no new export and only libSceLibcInternal's exports change. Unlike #14373, no_nid_postfixsymbol is added to libc: the 13.60 export inventory (ps5-1360-stubs) and its verified name map list these nine names only underlibSceLibcInternal, and the inventory has nolibclibrary at all, so nothing grounds them aslibc.prxexports.The new
core/libs/prx/libSceLibcInternal/Codecvt.cppholds the nine exports:do_members call the matching slot ofLibcCodecvtMethods_nid_no_patch():CodecvtAlwaysNoconv,CodecvtNoConversion,CodecvtUnshiftandCodecvtLength. They never read the facet's own vtable, so a derived facet that callscodecvt::do_ingets the base behaviour.std::invalid_argument.This PR also changes existing libc behaviour. On
main, libc'sCodecvtUnshift(theunshiftslot of everycodecvt<char, char>facet_Getcatbuilds) returnedok(0). It now returnsnoconv(3). [locale.codecvt.virtuals] Table 94 definesnoconvas "no termination is needed for this state_type", which holds for the statelesschar-to-charfacet, and microsoft/STLe1ed302683stl/inc/xlocaleL738-L742 returnsnoconvfromdo_unshift. The test covers it:guest_libc_internal_codecvtchecksdo_unshiftandunshifton the_Getcatfacet returnnoconv, and the existing assertion incore/libs/tests/GuestLocale.cppis updated from== 0to== 3.The standard
lengthanddo_lengthreturnint, but the vtable slot is typedstd::size_t. Both therefore keep only the low 32 bits of the slot's result. This gives the right value when a guest override returnsintineaxand leaves the upper half ofraxundefined.Changes:
core/libs/prx/libSceLibcInternal/Codecvt.cpp. The nine stubs are removed fromErr.cpp. The entry points are declared inprx/libSceLibcInternal/include/Api.hpp.core/libs/prx/libc/src/LocaleSupport.cpp:LibcCodecvtMethods_nid_no_patch()and theCodecvtUnshiftresult.guest_libc_internal_codecvt(core/libs/tests/GuestLibcInternalCodecvt.cpp). It checks:do_and public member on the facet_Getcatbuilds;maxagainst the range length, and an empty range;in,out,unshiftandlengthreach an overriding facet's slots with their arguments and return its results, includinglengthdropping the upper 32 bits of ado_lengthresult;do_members called on that overriding facet still give the base results;std::invalid_argumentfor a null facet and for a facet with no vtable.docs/dev/debt/libSceLibcInternal.md: the nine "prototype and behavior are unverified" lines are removed. A Functional entry is added for what the console was not checked for.tools/progress.pycollect_libraries():origin/main(b11c7bf84f): 9921 done of 37146 (libSceLibcInternal 92 done, 1045 todo; libc 1628 done, 19 todo).Tested
Only the libraries and the focused test targets were built, on head
24e372834e(based onorigin/mainb11c7bf84f). No title was run.ctest -R '^(guest_libc_internal_codecvt|guest_locale|guest_err|conventions_unknown_nids|conventions_debt_length|conventions_doc_links|debt_split)$'ran 3 times. Each run passed 7 of 7 tests with 0 failures.guest_libc_internal_codecvtis the new guest test.guest_localeholds the updatedCodecvtUnshiftassertion.guest_errbuilds from theErr.cppthe stubs were removed from.conventions_unknown_nids,conventions_debt_length,conventions_doc_linksanddebt_splitare the repository's checker self-tests for the conventions and the debt-file split. They were run because the debt file changed.core/libs/tests/test_public_headers.py --audit-only(Windows): "406 libraries, 28350 exports: unique declarations and umbrella coverage verified".objdump -pon the Windows build:libSceLibcInternal.prxexports each of the nine<NID>_nid_no_patch_cutnames once, and noPending3_027..035remains.libc.prxexports no_ZNKSt7codecvtIcc9_Mbstatetname; its only new symbol is the non-NIDLibcCodecvtMethods_nid_no_patch.main'sCodecvtUnshiftresult (return 0;) is restored.guest_libc_internal_codecvtfails 1 of 1 withlibc internal codecvt: do_unshift of codecvt<char, char> returns noconv, andguest_localefails too. Withreturn 3;back both pass.MSYS_NO_PATHCONV=1 python3 tools/check_conventions.py --base origin/main --title "<title>" --body <this body>: "All conventions checks passed."python3 tools/pr_overlap.py --branch feat/r2-codecvt-charexited 2 and printed "pr_overlap: overlap check failed closed; manually compare every reported PR branch before opening this one". It found no PR with the same exports or the same new files. It reported conflicting lines with feat(libSceLibcInternal): implement num_put<char>::put and time_put<char>::put #15715 only, and could not compare feat(aot): consolidate native ARM64 compiler, runtime and consumers #5021, fix(libs): share Sony CRT handler and lconv state between libc and libSceAmpr #7081, feat(libc): add std::__sce_v2::_Random_device, _Fiopen and setw #9526, feat(libc): export the messages facet vtable as data #10158, fix(libc): size the codecvt facet vtable to 104 bytes #10165, feat(libc): export the numpunct facet vtable as data #10200, feat(libc): export the time_put facet vtable as data #12510, feat(libc): export the money_get facet vtable as data #12511, feat(libc): export the money_put facet vtable as data #12518, feat(libc): export the wide time_put facet vtable as data #12704, fix(relinker): match AppContent utility import to provider #13486, feat(libSceLibcInternal): implement the msun trigonometric kernels #13778, feat(libSceLibcInternal): implement floating-point word access #13782, feat(libSceLibcInternal): implement _readdir_unlocked and _seekdir #13881, docs(debt): separate entries with blank lines and drop derived export totals #14212, feat(libSceLibcInternal): implement zero-return showmanyc exports #14401, feat(libSceLibcInternal): implement the placement operator delete and delete[] #14837 and feat(libSceLibcInternal): implement std::_MP_Add, _MP_Get, _MP_Mul and _MP_Rem #14936. I compared every one of them by hand, and also feat(libSceLibcInternal): implement the numpunct<char> members #14373 (numpunct<char>), feat(libSceLibcInternal): answer the codecvt and messages queries as firmware 13.42 does #15582 and feat(libSceLibcInternal): return from 52 empty facet members as firmware 13.42 does #15584 (other codecvt and facet members) and feat(libc): wire the codecvt<wchar_t,char> facet vtable #11172 (codecvt<wchar_t, char>vtable): for each I diffed the PR head against its merge base, searched the diff for the nine NIDs, the nine symbol names, thePending3_027..035stub names,Codecvt.cpp,CodecvtUnshiftandLibcCodecvtMethods, and rangit merge-treeof the PR head againstmainand against this branch.num_put<char>::putandtime_put<char>::put): no hits. It declaresLibcTimePutPattern_nid_no_patchon theGuestLocale.hppline where this PR declaresLibcCodecvtMethods_nid_no_patch, which is a text conflict; whichever merges second keeps both lines.WideCodecvtUnshiftfor the wide facet; it does not touchCodecvtUnshiftand merges with this branch cleanly.git merge-treeconflicts are the same against this branch as againstmain, so this branch adds none.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code